<template>
  <el-upload
    ref="uploadRef"
    v-loading="loading"
    :action="uploadUrl"
    :headers="uploadHeaders"
    :http-request="handleHttpRequest"
    :before-upload="handleBeforeUpload"
    list-type="picture-card"
    accept=".jpeg,.gif,.png,.jpg"
    :multiple="false"
    auto-upload
    :show-file-list="false"
    @success="handleSuccess"
    @error="handleError"
  >
    <div v-if="fileUrl" class="flex items-center justify-center">
      <img class="w-11/12" :src="fileUrl" />
    </div>
    <el-icon v-else><Plus /></el-icon>
    <!-- <template #file="{ file }">
      <img class="el-upload-list__item-thumbnail" :src="file.url" />
      <span class="el-upload-list__item-actions">
        <span
          v-if="!disabled"
          class="el-upload-list__item-delete"
          @click="handleRemove"
        >
          <el-icon><Delete /></el-icon>
        </span>
      </span>
    </template> -->
  </el-upload>
</template>

<script setup lang="ts">
import { Plus } from '@element-plus/icons-vue'
import type {
  UploadFile,
  UploadInstance,
  UploadRawFile,
  UploadRequestHandler
} from 'element-plus'
import { ajaxUpload } from 'element-plus/es/components/upload/src/ajax'

import { ResultEnum } from '@/apis/http/httpEnum'
import { useAppStore } from '@/stores/modules/app'
import ToastUtils from '@/utils/toast'

interface IProps {
  modelValue: string
}

interface IEmit {
  (event: 'update:modelValue', value: string): void
}
const emit = defineEmits<IEmit>()
const props = defineProps<IProps>()

const appStore = useAppStore()

const uploadRef = ref<UploadInstance>()
const loading = ref(false)
const cacheFileUrl = ref('')

// 显示图片地址
const fileUrl = computed(() => cacheFileUrl.value || props.modelValue)

// 图片上传地址
const uploadUrl = mergeBaseURL(`/${import.meta.env.VITE_API_VERSION}/upload`)

// 图片上传请求所携带的header
const uploadHeaders = computed(() => {
  return {
    Authorization: 'Bearer ' + appStore.token
  }
})

const handleHttpRequest: UploadRequestHandler = options => {
  const ajax = ajaxUpload(options)
  const xhr = ajax as XMLHttpRequest
  xhr.timeout = 10 * 1000 * 9
  xhr.ontimeout = () => {
    handleError()
  }
  return ajax
}

const handleSuccess = (e, uploadFile: UploadFile) => {
  const { code, message } = e
  const appStore = useAppStore()
  if (code === ResultEnum.SUCCESS) {
    emit('update:modelValue', mergeBaseURL(e.data.path))
    loading.value = false
    cacheFileUrl.value = uploadFile.url ?? ''
    return
  }

  if (code === ResultEnum.UNAUTHORIZED) {
    ToastUtils.showError(message)
    appStore.signOut()
    return
  }
  ToastUtils.showError(message)
  handleRemove()
}

const handleError = () => {
  ToastUtils.showError('logo上传失败')
  handleRemove()
}

const handleRemove = () => {
  // emit('update:modelValue', '')
  cacheFileUrl.value = ''
  loading.value = false
  uploadRef.value?.clearFiles()
}

const handleBeforeUpload = (rawFile: UploadRawFile) => {
  const isLt2M = rawFile.size / 1024 / 1024 < 2
  if (!isLt2M) {
    ToastUtils.showError('上传图片大小不能超过 2MB!')
    handleRemove()
    return false
  }
  loading.value = true
}

defineExpose({
  loading
})
</script>

<style scoped lang="scss">
:deep(.el-upload-list--picture-card),
:deep(.el-upload--picture-card),
:deep(.el-upload-list__item),
:deep(.el-upload-list__item) {
  @apply w-[82px] h-[82px] bg-white rounded overflow-hidden p-0 m-0;
  border-radius: 4px;
}
</style>
